package jp.sourceforge.akjrcp.ui;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;


import jp.sourceforge.akjrcp.dropsomething.FFMpegOptionEditor;
import jp.sourceforge.akjrcp.psp.PSPSyncView;
import jp.sourceforge.akjrcp.util.FTPInfo;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.preference.FieldEditor;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.FileDialog;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Table;
import org.eclipse.ui.PlatformUI;

public class GenericParametersFieldEditor extends FieldEditor {
	public static Log log=LogFactory.getLog(GenericParametersFieldEditor.class);
	
	private Button upButton, downButton, topButton, bottomButton;

	private Button newButton,editButton,deleteButton,copyButton,exportButton,exportAllButton,importButton;
	private Button deleteAll;
	// todo add new edit remove
	private GenericParametersTableViewer table;



	private Label label;

	private Composite menus;

	private Class optionEditorClass;
	private int dialogWidth=300;
	private int dialogHeight=350;
	public int getDialogHeight() {
		return dialogHeight;
	}



	public void setDialogHeight(int dialogHeight) {
		this.dialogHeight = dialogHeight;
	}



	public int getDialogWidth() {
		return dialogWidth;
	}



	public void setDialogWidth(int dialogWidth) {
		this.dialogWidth = dialogWidth;
	}



	public GenericParametersFieldEditor(String key, String description,
			Composite parent) {
		super(key, description, parent);

	}
	
	

	protected void adjustForNumColumns(int numColumns) {
		// adjust
		log.info("adjust:" + numColumns);
	}

	private Table getTable(Composite parent) {
		if (table == null) {
			
			table = new GenericParametersTableViewer(parent);
			
		}
		return table.getTable();
	}

	public class FixComposite extends Composite{

		public FixComposite(Composite parent, int style) {
			super(parent, style);
			
		}
		
		public Point computeSize(int wHint,
                int hHint,
                boolean changed){
			
			return new Point(480,300);
		}
		
	}
	protected void doFillIntoGrid(Composite parent, int numColumns) {
		Label label = getLabel(parent);
		GridData ld = new GridData();
		ld.horizontalSpan = numColumns;
		label.setLayoutData(ld);
		
		Composite fill=new Composite(parent,SWT.NONE);
		GridData gd1 = new GridData(GridData.FILL_HORIZONTAL);
		gd1.horizontalSpan = numColumns;//fill
		fill.setLayoutData(gd1);
		fill.setLayout(new GridLayout(2,false));
		
		FixComposite composite=new FixComposite(fill,SWT.NULL);
		composite.setLayout(new FillLayout());
		
		GridData gd = new GridData(GridData.FILL_HORIZONTAL);
		
		gd.grabExcessVerticalSpace=true;
		gd.grabExcessHorizontalSpace=true;
		//log.infocol:" + numColumns);
		//gd.horizontalSpan = numColumns - 1;
		//gd.minimumHeight = 300;
		//gd.minimumWidth = 400;
		composite.setLayoutData(gd); // should re-set new gridData
		
		Table table = getTable(composite);
		

		Composite menus = getMenus(fill);
		menus.setLayoutData(new GridData());// should re-set new gridData

	}

	private Label getLabel(Composite parent) {
		if (label == null) {
			label = new Label(parent, SWT.NULL);
			label.setText(getLabelText());

		}
		return label;
	}

	private Composite getMenus(Composite parent) {
		if (menus == null) {
			menus = new Composite(parent, SWT.NULL);

			menus.setLayout(new GridLayout());

			newButton = createButton(menus, Messages
					.getString("genericparameters.new"));
			editButton = createButton(menus, Messages
					.getString("genericparameters.edit"));
			copyButton = createButton(menus, Messages
					.getString("genericparameters.copy"));
			deleteButton = createButton(menus, Messages
					.getString("genericparameters.delete"));
			
			
			topButton = createButton(menus, Messages
					.getString("genericparameters.top"));
			upButton = createButton(menus, Messages
					.getString("genericparameters.up"));
			downButton = createButton(menus, Messages
					.getString("genericparameters.down"));
			bottomButton = createButton(menus, Messages
					.getString("genericparameters.bottom"));
			
			
			importButton = createButton(menus, Messages
					.getString("genericparameters.import"));
			exportButton = createButton(menus, Messages
					.getString("genericparameters.export"));
			exportAllButton = createButton(menus, Messages
					.getString("genericparameters.export_all"));
			
			deleteAll = createButton(menus, Messages
					.getString("genericparameters.delete_all"));

		}
		return menus;
	}

	public Button createButton(Composite p, String label) {
		Button bt = new Button(p, SWT.NULL);
		bt.setText(label);
		bt.addSelectionListener(new ButtonSelect());
		bt.setLayoutData(new GridData());
		return bt;
	}

	public class ButtonSelect implements SelectionListener {

		public void widgetSelected(SelectionEvent e) {
			//TODO
			int index=table.getTable().getSelectionIndex();
			if (e.widget == topButton) {
				GenericParameters setting=(GenericParameters) table.getGenericParameters().get(index);
				table.getGenericParameters().remove(setting);
				table.getGenericParameters().add(0,setting);
				table.refresh();
				
			}else if (e.widget == upButton) {
				GenericParameters setting=(GenericParameters) table.getGenericParameters().get(index);
				table.getGenericParameters().remove(setting);
				table.getGenericParameters().add(Math.max(0,index-1),setting);
				table.refresh();
				
			}else if (e.widget == downButton) {
				GenericParameters setting=(GenericParameters) table.getGenericParameters().get(index);
				table.getGenericParameters().remove(setting);
				table.getGenericParameters().add(Math.min(table.getGenericParameters().size(),index+1),setting);
				table.refresh();
				
			}else if (e.widget == bottomButton) {
				GenericParameters setting=(GenericParameters) table.getGenericParameters().get(index);
				table.getGenericParameters().remove(setting);
				table.getGenericParameters().add(table.getGenericParameters().size(),setting);
				table.refresh();
				
			} else if (e.widget == newButton) {
				GenericParametersEditorDialog dialog=new GenericParametersEditorDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell());
				//TODO support option editor..
				int result=dialog.open();
				if(result==Dialog.OK){
					table.refresh();
					
					GenericParameters newed=createNewGenericParameters(dialog);
					newed.setName(dialog.getName());
					newed.setComment(dialog.getComment());
					table.getGenericParameters().add(table.getGenericParameters().size(),newed);
					table.refresh();
				}else{
					log.info(result);
				}
				
			}else if (e.widget == editButton) {
				if(index>=0){
				GenericParameters setting=(GenericParameters) table.getGenericParameters().get(index);
				String command=GenericParameters.getCSVHeaderParamRemovedLine(GenericParameters.parametersToCsv(setting));
				log.info("command:"+command);
				GenericParametersEditorDialog dialog=new GenericParametersEditorDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell());
				dialog.setName(setting.getName());
				dialog.setComment(setting.getComment());
				dialog.setCommand(command);
				GenericParametersOptionEditor optionEditor=null;
				if(optionEditorClass!=null){
				try {
					optionEditor = (GenericParametersOptionEditor) optionEditorClass.newInstance();
				} catch (InstantiationException e1) {
					e1.printStackTrace();
				} catch (IllegalAccessException e1) {
					e1.printStackTrace();
				}
				dialog.setOptionEditor(optionEditor);
				}
				
				dialog.setParameters(setting.getParameters());
			
				dialog.setDialogWidth(dialogWidth);
				dialog.setDialogHeight(dialogHeight);
				int result=dialog.open();
				
				if(result==Dialog.OK){
					table.refresh();
					
					//use same
					if(optionEditorClass==null){//
					log.warn("maybe dont work");
					GenericParameters edited=GenericParameters.csvToParameters(dialog.getCommand());
					setting.setParameters(edited.getParameters());
					}else{
					//use new
					setting.setParameters(optionEditor.getParameters());
					}
					setting.setName(dialog.getName());
					setting.setComment(dialog.getComment());
					table.refresh();
				}else{
					log.info(result);
				}
				
				}
				
			}else if (e.widget == copyButton) {
				if(index>=0){
				GenericParameters setting=(GenericParameters) table.getGenericParameters().get(index);
				
				GenericParameters copied=GenericParameters.csvToParameters(GenericParameters.parametersToCsv(setting));
				
				table.getGenericParameters().add(table.getGenericParameters().size(),copied);
				table.refresh();
				}
				
			}else if (e.widget ==deleteButton) {
				if(index>=0){
				GenericParameters setting=(GenericParameters) table.getGenericParameters().get(index);
				
				table.getGenericParameters().remove(setting);
				//table.getGenericParameters().add(table.getGenericParameters().size(),setting);
				table.refresh();
				
				}
				
			}else if (e.widget == importButton) {
				FileDialog dialog=new FileDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),SWT.OPEN);
				dialog.setFilterExtensions(new String[]{"*.csv"});
				String path=dialog.open();
				if(path!=null){
					
					try {
						String text=FileUtils.readFileToString(new File(path));
						GenericParameters[] settings = GenericParametersTableViewer.toGenericParameters(text);
						for (int i = 0; i < settings.length; i++) {
							table.getGenericParameters().add(settings[i]);
						}
						table.refresh();
					} catch (IOException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
				}
				
			}else if (e.widget == exportButton) {
				if(index>=0){
				GenericParameters setting=(GenericParameters) table.getGenericParameters().get(index);
				FileDialog dialog=new FileDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),SWT.SAVE);
				dialog.setFilterExtensions(new String[]{"*.csv"});
				String path=dialog.open();
				if(path!=null){
					//GenericParameters infos[] = (GenericParameters[]) table.getGenericParameters().toArray(new GenericParameters[0]);
					
					String text=toStoreString(new GenericParameters[]{setting});//save new value.
					
					//String text=getPreferenceStore().getString(getPreferenceName());
					text=StringUtils.replace(text, "\n", "\r\n");
					try {
						FileUtils.writeStringToFile(new File(path), text);
					} catch (IOException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
				}
				}
			}else if (e.widget == exportAllButton) {
				FileDialog dialog=new FileDialog(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(),SWT.SAVE);
				dialog.setFilterExtensions(new String[]{"*.csv"});
				String path=dialog.open();
				if(path!=null){
					GenericParameters infos[] = (GenericParameters[]) table.getGenericParameters().toArray(new GenericParameters[0]);
					
					String text=toStoreString(infos);//save new value.
					
					//String text=getPreferenceStore().getString(getPreferenceName());
					text=StringUtils.replace(text, "\n", "\r\n");
					try {
						FileUtils.writeStringToFile(new File(path), text);
					} catch (IOException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
				}
			}else if (e.widget ==deleteAll) {
				
					
					table.getGenericParameters().removeAll(table.getGenericParameters());
					//table.getGenericParameters().add(table.getGenericParameters().size(),setting);
					table.refresh();
					
					
					
				}
			
			//saveStore();
		}

		

		public void widgetDefaultSelected(SelectionEvent e) {
			
		}

	}

	protected GenericParameters createNewGenericParameters(
			GenericParametersEditorDialog dialog) {
		return new GenericParameters();//empty should overwrite
	}
	/*
	 * private String toStoreString(List list){ StringBuffer buffer=new
	 * StringBuffer(); FTPInfo infos[]=(FTPInfo[]) list.toArray(new FTPInfo[0]);
	 * log.info(infos.length); log.info(table.getInput());
	 * for (int i = 0; i < infos.length; i++) {
	 * buffer.append(toStoreString(infos[i])+"\n"); } return buffer.toString(); }
	 */
	




	protected void doLoad() {
		GenericParameters[] settings = GenericParametersTableViewer.toGenericParameters(getPreferenceStore().getString(
				getPreferenceName()));
		for (int i = 0; i < settings.length; i++) {
			table.getGenericParameters().add(settings[i]);
		}
		table.refresh();
	}
	
	

	protected void doLoadDefault() {
		
		table.getGenericParameters().removeAll(table.getGenericParameters());
		
		String value=getPreferenceStore().getDefaultString(
				getPreferenceName());
		
		GenericParameters[] settings = GenericParametersTableViewer.toGenericParameters(getPreferenceStore().getDefaultString(
				getPreferenceName()));
		for (int i = 0; i < settings.length; i++) {
			table.getGenericParameters().add(settings[i]);
		}
		
		table.refresh();
	}

	private void saveStore() {
		
		setPresentsDefaultValue(false);//don't care

		
		GenericParameters infos[] = (GenericParameters[]) table.getGenericParameters().toArray(new GenericParameters[0]);
		String oldValue=sortGenericCSV(getPreferenceStore().getString(getPreferenceName()));
		String newValue=sortGenericCSV(toStoreString(infos));
		
		/*
		 * i have no idea why i had to sort data.
		 * if problem happend again back to code.
		 */
		//String oldValue=getPreferenceStore().getString(getPreferenceName());
		//String newValue=toStoreString(infos);
		
		
		//set only difference
		if(!oldValue.equals(newValue)){
		log.info("save store");
		getPreferenceStore().setValue(getPreferenceName(),newValue);
		}
	}
	
	/*
	 * need to compare settings
	 * just sort parameters for comparing
	 */
	public String sortGenericCSV(String text){
		String[] values=text.split("\n");
		//Arrays.sort(values);	//keep item order otherwise order always
		StringBuffer result=new StringBuffer();
		for (int i = 0; i < values.length; i++) {
			String[] csvs=values[i].split(",");
			Arrays.sort(csvs);
			for (int j = 0; j < csvs.length; j++) {
				result.append(csvs[j]);
				if(j!=csvs.length-1){
					result.append(",");
				}
			}
			result.append("\n");
		}
		return result.toString();
	}
	
	public static String toStoreString(GenericParameters[] settings){
		StringBuffer buffer = new StringBuffer();
		for (int i = 0; i < settings.length; i++) {
			buffer.append(GenericParametersTableViewer.toStoreString(settings[i]) + "\n");
		}
		return buffer.toString();
	}

	protected void doStore() {
		saveStore();
	}

	public int getNumberOfControls() {
		return 2;
	}



	public Class getOptionEditorClass() {
		return optionEditorClass;
	}



	public void setOptionEditorClass(Class optionEditorClass) {
		this.optionEditorClass = optionEditorClass;
	}





	

}
